package it.uniba.di.mas.jpnde.behaviour;

import it.uniba.di.mas.jpnde.core.PlaceEvent;
import it.uniba.di.mas.jpnde.core.PN;
import it.uniba.di.mas.jpnde.core.Place;
import it.uniba.di.mas.jpnde.core.Transition;
import jade.content.onto.basic.Action;
import jade.core.ContainerID;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.SequentialBehaviour;
import jade.domain.FIPANames;
import jade.domain.JADEAgentManagement.CreateAgent;
import jade.domain.JADEAgentManagement.JADEManagementOntology;
import jade.lang.acl.ACLMessage;
import jade.util.leap.List;

public class PNManagerInit extends Behaviour{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final static short AWAIT_PN=0;
	private final static short DELIVERY_PN=1;
	private final static short OK=2;
	private final static short ERROR=3;
	
	private int state=AWAIT_PN;
	private PN pn=null;
	
	@Override
	public void action() {
		// TODO Auto-generated method stub
		
		switch(state){
		case AWAIT_PN:
			receivePN();
			break;
		case DELIVERY_PN:
			delivery();
			break;
		}		
	}

	@Override
	public boolean done() {
		// TODO Auto-generated method stub
		return (state==ERROR)||(state==OK);
	}
	
	private void receivePN(){
		System.out.println("PNManagerInit.receivePN");
		ACLMessage message=myAgent.receive();
		try
			{
			if (message!=null)
				{
				ACLMessage reply=message.createReply();
				if ((message.getPerformative()!=ACLMessage.REQUEST)||
				    !(message.getContentObject() instanceof PN))
					{
						state=ERROR;
						reply.setPerformative(ACLMessage.FAILURE);
					}	
				else
					{
						pn=(PN)message.getContentObject();
						state=DELIVERY_PN;
						reply.setPerformative(ACLMessage.INFORM);
					}
				myAgent.send(reply);
				}
			else
				block();
			}
		catch(Exception e)
			{e.printStackTrace();}
	
	}
	
	private void delivery(){
		System.out.println("PNManagerInit.delivery :"+pn.getId());
		
		SequentialBehaviour seqBehaviour=new SequentialBehaviour(myAgent){
			public int onEnd() {
				int ret=super.onEnd();
				System.out.println("SequentialBehaviour.onEnd :"+pn.getId());
				if (pn.isDeliverated())
					myAgent.addBehaviour(new PNManagerRun(pn));
				else
					myAgent.doDelete();
				return ret;
			}
		}; 
		
		// Delivery Transition
		List transactions=pn.getTransitions();
		for(int i=0;i<transactions.size();i++)
			{
			Transition t=(Transition)transactions.get(i);
			t.setManagerId(myAgent.getName());
			
			CreateAgent ca=new CreateAgent();
			String agentId=t.getId()+"."+pn.getId();
			ca.setAgentName(agentId);
			ca.setClassName("it.uniba.di.mas.jpnde.agent.PNTransition");
			
			try
			{
				if (!t.getContainer().equals(""))
					ca.setContainer(new ContainerID(t.getContainer(),null));
				else
					ca.setContainer(new ContainerID(myAgent.getContainerController().getContainerName(),null));
				
				Action act=new Action(myAgent.getAMS(),ca);
				ACLMessage request=new ACLMessage(ACLMessage.REQUEST);
				request.addReceiver(myAgent.getAMS());
				request.setOntology(JADEManagementOntology.getInstance().getName());
				request.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
				request.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);
			
				myAgent.getContentManager().fillContent(request, act);
				
				seqBehaviour.addSubBehaviour(new PNManagerDelivery(seqBehaviour,myAgent,
								request,t,agentId));
				
			}
			catch (Exception e){
				e.printStackTrace();
				state=ERROR;
				}
		} // End for
		
		// Delivery Event
		List places=pn.getPlaces();
		for(int i=0;i<places.size();i++)
			{
			if (((Place)places.get(i)).getEvent()!=null)
				{
				PlaceEvent event=((Place)places.get(i)).getEvent();
				event.setManagerId(myAgent.getName());
			
				CreateAgent ca=new CreateAgent();
				String agentId=event.getId()+"."+pn.getId();
				ca.setAgentName(agentId);
				ca.setClassName("it.uniba.di.mas.jpnde.agent.PNEvent");
			
				try
				{
				ca.setContainer(new ContainerID(myAgent.getContainerController().getContainerName(),null));
				
				Action act=new Action(myAgent.getAMS(),ca);
				ACLMessage request=new ACLMessage(ACLMessage.REQUEST);
				request.addReceiver(myAgent.getAMS());
				request.setOntology(JADEManagementOntology.getInstance().getName());
				request.setLanguage(FIPANames.ContentLanguage.FIPA_SL);
				request.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);
			
				myAgent.getContentManager().fillContent(request, act);
				
				seqBehaviour.addSubBehaviour(new PNManagerDelivery(seqBehaviour,myAgent,
								request,event,agentId));
				
				}
				catch (Exception e){
					e.printStackTrace();
					state=ERROR;
					}
			} // End if Event
		} // End for
		
		myAgent.addBehaviour(seqBehaviour);
		state=OK;
	}
	
	public int onEnd() {
		System.out.println("PNManagerInit.onEnd :"+pn.getId());
		int ret=super.onEnd();
		if (state==ERROR)
			myAgent.doDelete();
		return ret;
	}
	
	
}
